package com.chlp.core.framework.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.sql.DataSource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Druid 数据源配置类 参照：https://blog.csdn.net/wangmx1993328/article/details/81865153
 * <p>
 * Spring Boot 2.0 以上默认使用 com.zaxxer.hikari.HikariDataSource 数据源，可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源
 * 但可以 通过 spring.datasource.type 指定数据源
 * <p>
 *
 * <dependency>
 * <groupId>com.alibaba</groupId>
 * <artifactId>druid</artifactId>
 * <version>${druid.version}</version>
 * </dependency>
 *
 * <p>
 * application.properties配置文件：spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
 *
 * @author 陈礼鹏
 */
@Configuration
public class DruidDataSourceConfig {

	@Value("${spring.datasource.username}")
	private String username;

	/**
	 * 将自定义的 Druid 数据源添加到容器中，不再让 Spring Boot 自动创建
	 * 这样做的目的是：绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource 从而让它们生效
	 *
	 * @ ConfigurationProperties(prefix = "spring.datasource")：
	 * 作用就是将全局配置文件中前缀为spring.datasource 的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
	 */
	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DataSource druidDataSource() {
		return new DruidDataSource();
	}

	/**
	 * 配置 Druid 监控 之  管理后台的 Servlet
	 * 内置 Servler 容器时没有web.xml 文件，所以使用 Spring Boot 的注册 Servlet 方式
	 */
	@Bean
	public ServletRegistrationBean<Servlet> statViewServlet() {
		ServletRegistrationBean<Servlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
		// loginUsername：Druid 后台管理界面的登录账号
		// loginPassword：Druid 后台管理界面的登录密码
		// allow：Druid 后台允许谁可以访问
		// initParams.put("allow", "localhost")：表示只有本机可以访问
		// initParams.put("allow", "")：为空或者为null时，表示允许所有访问
		// deny：Druid 后台拒绝谁访问
		// initParams.put("deny", "192.168.1.20");表示禁止此ip访问
		Map<String, String> initParams = new HashMap<>(8);
		initParams.put("loginUsername", "admin");
		initParams.put("loginPassword", "123456");
		initParams.put("allow", "");
		/*initParams.put("deny", "192.168.1.20");*/

		// 设置初始化参数
		bean.setInitParameters(initParams);
		return bean;
	}

	/**
	 * 配置 Druid 监控 之  web 监控的 filter
	 * WebStatFilter：用于配置Web和Druid数据源之间的管理关联监控统计
	 */
	@Bean
	public FilterRegistrationBean<Filter> webStatFilter() {
		FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
		bean.setFilter(new WebStatFilter());

		//  exclusions：设置哪些请求进行过滤排除掉，从而不进行统计
		Map<String, String> initParams = new HashMap<>(8);
		initParams.put("exclusions", "*.js,*.css,/druid/*");
		bean.setInitParameters(initParams);

		//  "/*" 表示过滤所有请求
		bean.setUrlPatterns(Collections.singletonList("/*"));
		return bean;
	}

}